package cn.js.sangu.unitStore.utils;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

public class PoiExcelUtils {
    private final static String XLS = "xls";
    private final static String XLSX = "xlsx";
    private final static String DATE_FORMAT = "yyyy/MM/dd";
    private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat(DATE_FORMAT);

    /**
     * 读入excel文件，解析后返回(解析全天数据EXCEL)
     * 
     * @param file
     * @throws IOException
     */
    public static List<String> readExcel(MultipartFile file) throws IOException {
        // 检查文件
        checkFile(file);
        // 获得Workbook工作薄对象
        try (Workbook workbook = getWorkBook(file)) {
            // 创建返回对象，把每行中的值作为一个数组，所有行作为一个集合返回
            List<String> list = new ArrayList<>();
            if (workbook != null) {
                // 获得当前sheet工作表
                Sheet sheet = workbook.getSheetAt(0);
                if (sheet != null) {
                    // 获得当前sheet的开始行
                    int firstRowNum = 1;
                    // 获得当前sheet的结束行
                    int lastRowNum = 102;
                    // 循环所有行
                    for (int rowNum = firstRowNum; rowNum <= lastRowNum; rowNum++) {
                        // 获得当前行
                        Row row = sheet.getRow(rowNum);
                        if (row == null) {
                            continue;
                        }
                        // 获得当前行的开始列
                        int firstCellNum = row.getFirstCellNum();
                        // 获得当前行的列数
                        int lastCellNum = 26;
                        // 循环当前行
                        for (int cellNum = firstCellNum; cellNum <= lastCellNum; cellNum++) {
                            Cell cell = row.getCell(cellNum);
                            String cellValue = getCellValue(cell);
                            list.add(cellValue);
                        }
                    }
                }
            }
            return list;
        }
    }

    /**
     * 读入excel文件，解析后返回(解析高峰数据EXCEL)
     * 
     * @param file
     * @throws IOException
     */
    public static List<String> readPeakExcel(MultipartFile file) throws IOException {
        // 检查文件
        checkFile(file);
        // 获得Workbook工作薄对象
        try (Workbook workbook = getWorkBook(file)) {
            // 创建返回对象，把每行中的值作为一个数组，所有行作为一个集合返回
            List<String> list = new ArrayList<>();
            if (workbook != null) {
                // 获得当前sheet工作表
                Sheet sheet = workbook.getSheetAt(0);
                if (sheet != null) {
                    // 获得当前sheet的开始行
                    int firstRowNum = 3;
                    // 获得当前sheet的结束行
                    int lastRowNum = 104;
                    // 循环所有行
                    for (int rowNum = firstRowNum; rowNum <= lastRowNum; rowNum++) {
                        // 获得当前行
                        Row row = sheet.getRow(rowNum);
                        if (row == null) {
                            continue;
                        }
                        // 获得当前行的开始列
                        int firstCellNum = row.getFirstCellNum();
                        // 获得当前行的列数
                        int lastCellNum = 11;
                        // 循环当前行
                        for (int cellNum = firstCellNum; cellNum <= lastCellNum; cellNum++) {
                            Cell cell = row.getCell(cellNum);
                            String cellValue = getCellValue(cell);
                            list.add(cellValue);
                        }
                    }
                }
            }
            return list;
        }
    }

    /**
     * 读入excel文件，解析后返回(解析监所数据EXCEL)
     * 
     * @param file
     * @throws IOException
     */
    public static List<String> readPrisonsExcel(MultipartFile file) throws IOException {
        // 检查文件
        checkFile(file);
        // 获得Workbook工作薄对象
        try (Workbook workbook = getWorkBook(file)) {
            // 创建返回对象，把每行中的值作为一个数组，所有行作为一个集合返回
            List<String> list = new ArrayList<>();
            if (workbook != null) {
                // 获得当前sheet工作表
                Sheet sheet = workbook.getSheetAt(0);
                if (sheet != null) {
                    // 获得当前sheet的开始行
                    int firstRowNum = 1;
                    // 获得当前sheet的结束行
                    int lastRowNum = sheet.getLastRowNum();
                    // 循环所有行
                    for (int rowNum = firstRowNum; rowNum <= lastRowNum; rowNum++) {
                        // 获得当前行
                        Row row = sheet.getRow(rowNum);
                        if (row == null) {
                            continue;
                        }
                        // 获得当前行的开始列
                        int firstCellNum = row.getFirstCellNum();
                        // 获得最后一列的列数
                        int lastCellNum = 14;
                        // 循环当前行
                        for (int cellNum = firstCellNum; cellNum <= lastCellNum; cellNum++) {
                            Cell cell = row.getCell(cellNum);
                            String cellValue = getCellValue(cell);
                            list.add(cellValue);
                        }
                    }
                }
            }
            return list;
        }
    }

    // 校验文件是否合法
    public static void checkFile(MultipartFile file) throws IOException {
        // 判断文件是否存在
        if (null == file || file.isEmpty()) {
            throw new FileNotFoundException("文件不存在或为空！");
        }
        // 获得文件名
        String fileName = file.getOriginalFilename();
        if (fileName == null || fileName.trim().isEmpty()) {
            throw new IOException("文件名无效！");
        }
        // 判断文件是否是excel文件
        if (!fileName.toLowerCase().endsWith(XLS) && !fileName.toLowerCase().endsWith(XLSX)) {
            throw new IOException(fileName + "不是excel文件");
        }
    }

    public static Workbook getWorkBook(MultipartFile file) throws IOException {
        // 获得文件名
        String fileName = file.getOriginalFilename();
        if (fileName == null) {
            throw new IOException("文件名无效！");
        }
        // 创建Workbook工作薄对象，表示整个excel
        Workbook workbook = null;
        try (InputStream is = file.getInputStream()) {
            // 根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象
            if (fileName.endsWith(XLS)) {
                // 2003
                workbook = new HSSFWorkbook(is);
            } else if (fileName.endsWith(XLSX)) {
                // 2007
                workbook = new XSSFWorkbook(is);
            }
        }
        return workbook;
    }

    public static String getCellValue(Cell cell) {
        if (cell == null) {
            return "";
        }

        CellType cellType = cell.getCellType();

        // 处理数字类型（包括日期）
        if (cellType == CellType.NUMERIC) {
            // 检查是否是日期类型
            if (DateUtil.isCellDateFormatted(cell)) {
                try {
                    Date date = cell.getDateCellValue();
                    return DATE_FORMATTER.format(date);
                } catch (Exception e) {
                    // 如果日期格式化失败，回退到数字格式
                    return String.valueOf(cell.getNumericCellValue());
                }
            } else {
                // 处理纯数字
                double numericValue = cell.getNumericCellValue();
                // 判断是否为整数
                if (numericValue % 1 == 0) {
                    return String.valueOf((long) numericValue);
                } else {
                    return String.valueOf(numericValue);
                }
            }
        }
        // 处理字符串类型
        else if (cellType == CellType.STRING) {
            return cell.getStringCellValue() != null ? cell.getStringCellValue().trim() : "";
        }
        // 处理布尔类型
        else if (cellType == CellType.BOOLEAN) {
            return String.valueOf(cell.getBooleanCellValue());
        }
        // 处理公式类型
        else if (cellType == CellType.FORMULA) {
            try {
                // 尝试获取公式计算结果
                CellType formulaResultType = cell.getCachedFormulaResultType();
                if (formulaResultType == CellType.NUMERIC) {
                    if (DateUtil.isCellDateFormatted(cell)) {
                        return DATE_FORMATTER.format(cell.getDateCellValue());
                    } else {
                        double numericValue = cell.getNumericCellValue();
                        if (numericValue % 1 == 0) {
                            return String.valueOf((long) numericValue);
                        } else {
                            return String.valueOf(numericValue);
                        }
                    }
                } else if (formulaResultType == CellType.STRING) {
                    return cell.getStringCellValue() != null ? cell.getStringCellValue().trim() : "";
                } else if (formulaResultType == CellType.BOOLEAN) {
                    return String.valueOf(cell.getBooleanCellValue());
                }
            } catch (Exception e) {
                // 如果无法获取公式结果，返回公式本身
                return cell.getCellFormula();
            }
            return cell.getCellFormula();
        }
        // 处理空值
        else if (cellType == CellType.BLANK) {
            return "";
        }
        // 处理错误类型
        else if (cellType == CellType.ERROR) {
            return "非法字符";
        }
        // 未知类型
        return "未知类型";
    }
}